package com.liang.exam.controller;

import com.liang.exam.utils.TokenValidator;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import com.liang.exam.entity.Result;
import com.liang.exam.entity.Student;
import com.liang.exam.entity.Teacher;
import com.liang.exam.service.StudentService;
import com.liang.exam.service.TeacherService;
import com.liang.exam.utils.IdentifyCodeUtil;
import com.liang.exam.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.liang.exam.utils.Md5Util;

import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;

@RestController
public class LoginController {

    @Autowired
    private StudentService studentService;
    
    @Autowired
    private TeacherService teacherService;


    @Autowired
    private TokenValidator tokenValidator;



    /**
     * 学生教师管理员登录
     * @param request
     * @return
     */
    @RequestMapping ("/login")
    public Result<String> Login(HttpServletRequest request) {
        String account = request.getParameter("account");
        String password = request.getParameter("password");
        String type = request.getParameter("type");
        String inputCode = request.getParameter("identifyCode"); // 获取用户输入的验证码

        HttpSession session = request.getSession();
        String sessionCode = (String) session.getAttribute("identifyCode"); // 从session中获取存储的验证码

        // 验证验证码
        if (sessionCode == null || !sessionCode.equalsIgnoreCase(inputCode)) {
            return Result.error("验证码错误");// 返回验证码错误信息
        }

        if (type == null || type.trim().isEmpty()) {
            return Result.error("请选择登录类型");
        }

        if(type.equals("student")) {
            return handleStudentLogin(account, password,request);
        }else{
            return handleTeacherLogin(account, password, type);
        }
    }

    @GetMapping("/admin")
    public String admin() {
        return "admin";
    }

    @GetMapping("/teacher")
    public String teacher() {
        return "teacher";
    }

    private Result<String> handleStudentLogin(String account, String password, HttpServletRequest request) {
        Student login = studentService.findByAccount(account);

        if (login == null)
            return Result.error("用户不存在");

        if (login.getUserName().equals(password)) {
            String ipAddress = request.getRemoteAddr();
            Student existingBinding = studentService.findByIpAddress(ipAddress);
            // 检查该 IP 地址是否已经被其他学生使用
            if (existingBinding != null&&existingBinding.getIpAddress() != null && !(existingBinding.getId()==login.getId())) {
                return Result.error("该 IP 地址已经被其他学生使用");
            }
            // 检查该学生是否已经在其他 IP 地址上登录
            Student studentBinding = studentService.findById(login.getId());
            if (studentBinding!=null&&studentBinding.getIpAddress() != null && !studentBinding.getIpAddress().equals(ipAddress)) {
                return Result.error("该学生已经在其他 IP 地址上登录");
            }
            // 绑定 IP 和学生
            if (studentBinding.getIpAddress()==null) {
                studentService.save(ipAddress, login.getId());
            }

            Map<String, Object> claims = new HashMap<>();
            claims.put("username", login.getUserName());
            claims.put("account", login.getAccount());
            claims.put("role", login.getRole());
            claims.put("id", login.getId());
            String token = JwtUtil.genToken(claims);
            //把token存储到redis中
            tokenValidator.storeToken(token);
            String redirectUrl = "/student/home";
            return Result.success("登录成功",token, redirectUrl);
        }
        return Result.error("用户名或密码错误");
    }

    private Result<String> handleTeacherLogin(String account, String password,String type) {
        Teacher login = teacherService.findByAccount(account);
        if (login == null) {
            return Result.error("用户不存在");
        }

        // 检查密码
        if (!login.getPassword().equals(Md5Util.getMd5Encryption(password))) {
            return Result.error("用户名或密码错误");
        }

        // 角色权限检查
        if (type.equals("teacher")) {
            if (login.getRole().equals("1")) {
                // 允许管理员选择教师登录，直接继续执行
            } else if (!login.getRole().equals("0")) {
                return Result.error("该账号不是教师角色，无法登录");
            }
        } else if (type.equals("admin")) {
            if (!login.getRole().equals("1")) {
                return Result.error("该账号不是管理员角色，无法登录");
            }
        }

        // 生成 token 和存储到 Redis
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", login.getUserName());
        claims.put("account", login.getAccount());
        claims.put("role", login.getRole());
        claims.put("id", login.getId());
        String token = JwtUtil.genToken(claims);

        // 存储 token 到 Redis
        tokenValidator.storeToken(token);
        // 确定重定向目标
        String redirectUrl = type.equals("teacher") ? "/teacher/home" : "/admin/home";
        // 返回成功结果和重定向 URL
        return Result.success("登录成功",token, redirectUrl);
    }



    /**
     * 退出登录
     * @param token
     * @return
     */

    @PatchMapping("/logout")
    public Result<String> logout(@RequestHeader("Authorization") String token) {
        tokenValidator.invalidateToken(token);
        System.out.println("token:"+token);
        return Result.success("退出成功");
    }

    /**
     * 获取验证码,传到前端
     * @param response
     */
    @RequestMapping("/identifyImage")
    public void identifyImage(HttpServletResponse response, HttpSession session){
        //创建随机验证码
        IdentifyCodeUtil utils = new IdentifyCodeUtil();
        String identifyCode = utils.getIdentifyCode();
        //session存入验证码
        session.setAttribute("identifyCode", identifyCode);
        //根据验证码创建图片
        BufferedImage identifyImage = utils.getIdentifyImage(identifyCode);
        //回传给前端
        utils.responseIdentifyImg(identifyImage,response);
    }




}
